package com.javaspeak.concurrency.pattern.actor;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.internal.TextListener;
import org.junit.runner.JUnitCore;

import com.javaspeak.concurrency.pattern.actor.ActorRegistry;
import com.javaspeak.concurrency.pattern.actor.ActorRegistryImpl;
import com.javaspeak.concurrency.pattern.application.ExceptionActor;
import com.javaspeak.concurrency.pattern.application.ExceptionActorImpl;
import com.javaspeak.concurrency.pattern.application.StartApplication;
import com.javaspeak.concurrency.pattern.application.Trade;

/**
 * @author John Dickerson
 */
public class AssynchronousExceptionActorTest {

    public Logger logger = Logger.getLogger( StartApplication.class );

    private Collection<Trade> getTrades( long numberTrades ){

        Collection<Trade> trades = new ArrayList<Trade>( ( int )numberTrades );

        for ( int i=0; i<numberTrades; i++ ){

            Trade trade =
                new Trade( new Long( i ), new BigDecimal( i * 1000 ),
                        new BigDecimal( i * 100 ), Calendar.getInstance() );

            trades.add( trade );
        }

        return trades;
    }


    @Test
    public void testAssynchronousExceptions(){

        long numberTrades = 10000;

        Collection<Trade> trades = getTrades( numberTrades );

        ActorRegistry actorRegistry = ActorRegistryImpl.getInstance();
        actorRegistry.registerActor( new ExceptionActorImpl() );

        ExceptionActor exceptionActor =
            ( ExceptionActor )actorRegistry.getActor(
                    ExceptionActor.class );

        for ( Trade trade : trades ){

            // Asynchronous Exception
            try {
                exceptionActor.throwExceptionIfAmountDivisableBy_11(
                    trade );
            }
            catch( Exception e ){

                org.junit.Assert.fail( "Should not catch exception" );
            }
        }

        actorRegistry.shutDown();
    }


    public static void main( String args[] ){

        BasicConfigurator.resetConfiguration();
        BasicConfigurator.configure();

        JUnitCore junitCore = new JUnitCore();
        junitCore.addListener( new TextListener( System.out ) );
        junitCore.run( AssynchronousExceptionActorTest.class );
    }
}
